﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComputerArchitecture.Core;
using ComputerArchitecture.Core.Logging;
using ComputerArchitecture.Numbers;
using ComputerArchitecture.Units.Interfaces;

namespace ComputerArchitecture.Units.Complement
{
    public class ComplementSubstractUnit : LoggingObject, ISubstractUnit
    {
        #region Fields

        private readonly IAdderUnit _adderUnit;
        private readonly INegateUnit _negateUnit;

        #endregion

        #region Constructors

        public ComplementSubstractUnit(ILoggingService loggingService, IAdderUnit adderUnit, INegateUnit negateUnit)
            : base(loggingService)
        {
            ArgumentValidator.NullValidate(adderUnit);
            _adderUnit = adderUnit;
            ArgumentValidator.NullValidate(negateUnit);
            _negateUnit = negateUnit;
        }

        #endregion

        #region Methods

        public ISignedBitNumber Substract(ISignedBitNumber first, ISignedBitNumber second, out bool overflow)
        {
            ArgumentValidator.NullValidate(first);
            ArgumentValidator.NullValidate(second);
            bool hasError = false;
            NegateSpecialCase specialCase;
            ISignedBitNumber negateSecond = _negateUnit.Negate(second, out specialCase, out hasError);
            ISignedBitNumber result = _adderUnit.Add(first, negateSecond, out overflow);
            if (hasError && specialCase == NegateSpecialCase.MaxNegativeValue)
            {
                overflow = true;
            }
            return result;
        }

        #endregion
    }
}
